package com.wintop.springbootjwt.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.wintop.springbootjwt.annotation.PassToken;
import com.wintop.springbootjwt.annotation.UserLoginToken;
import com.wintop.springbootjwt.utils.Result;
import com.wintop.springbootjwt.utils.UserSecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Component
public class UserSecurityHandlerInterceptor implements HandlerInterceptor {
    @Autowired
    UserSecurityUtil securityUtil;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        boolean check = true;
        //如果不是映射到方法直接放行通过
        if (!(handler instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        // 判断是否有 passtoken注解,如果有通过 不进行token校验
        if(method.isAnnotationPresent(PassToken.class)){
            PassToken annotation = method.getAnnotation(PassToken.class);
            if (annotation.required()){
                return true;
            }
        }
        // 如果有UserLoginToken注解 则校验 token
        if (method.isAnnotationPresent(UserLoginToken.class)){
            UserLoginToken annotation = method.getAnnotation(UserLoginToken.class);
            if (annotation.required()){
                check = securityUtil.verifyWebToken(request, response);
                if (!check){
                    Map<String,Object> map = new HashMap<>();
                    map.put("code",401);
                    map.put("msg","未授权");
                    writeResponse(response,HttpStatus.UNAUTHORIZED,Result.ok(map));
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 写 http 相应状态
     * @param resp
     * @param status
     * @param result
     * @throws IOException
     */
    private void writeResponse(HttpServletResponse resp, HttpStatus status,Result result) throws IOException {
        ObjectMapper objectMapper = new ObjectMapper();
        resp.setStatus(status.value());
        resp.setContentType("application/json; charset=utf-8");
        resp.getWriter().write(objectMapper.writeValueAsString(result));
    }



    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
